#include "MQTTSubscriber.h"

MQTTSubscriber::MQTTSubscriber(const char *host, const char *client_id,
                               const char *topic, int qos)
    : BaseMQTTClient(client_id, host), default_topic(topic), default_qos(qos) {}

/**
 * @brief 订阅指定主题（Topic）
 *
 * 本函数通过 mosquitto 库向 MQTT Broker 发送 SUBSCRIBE 报文，
 * 一旦订阅成功，Broker 将在该主题有消息发布时主动推送消息，
 * 并触发客户端注册的消息回调函数（on_message）。
 *
 * @note 订阅过程是异步的，调用本函数后并不会立即接收消息。
 *       实际的订阅结果会在 mosquitto 的回调函数中返回。
 */
void MQTTSubscriber::subscribe() {
  /**
   * mosquitto_subscribe()
   * @param mosq          MQTT 客户端实例指针
   * @param mid           消息 ID（可为 nullptr，不关心时）
   * @param sub           要订阅的主题（C 字符串）
   * @param qos           服务质量等级 (0, 1, 或 2)
   *
   * @return MOSQ_ERR_SUCCESS 订阅请求成功发送
   *         其他返回值：表示订阅请求失败
   */
  int ret =
      mosquitto_subscribe(mosq, nullptr, default_topic.c_str(), default_qos);
  if (ret == MOSQ_ERR_SUCCESS)
    std::cout << "✅ 已订阅主题: " << default_topic << std::endl;
  else
    std::cerr << "❌ 订阅失败: " << mosquitto_strerror(ret) << std::endl;
}

/**
 * @brief 设置消息接收回调函数
 *
 * 本函数用于注册一个回调函数，当客户端接收到 Broker 推送的消息时，
 * 该回调函数会被自动调用。
 *
 * @param callback  用户自定义的回调函数指针，
 *        格式必须为：
 *        void callback(struct mosquitto *mosq,
 *                     void *obj,
 *                     const struct mosquitto_message *msg);
 *
 * @note
 *  - 这是异步机制：只有在 `mosquitto_loop_start()` 启动循环后，
 *    并且有消息到达时才会触发。
 *  - 每个客户端实例只能同时注册一个消息回调函数。
 *  - 若多次调用该函数，后一次会覆盖前一次注册的回调。
 */
void MQTTSubscriber::set_message_callback(void (*callback)(
    struct mosquitto *, void *, const struct mosquitto_message *)) {
  /**
   * mosquitto_message_callback_set()
   * @param mosq      MQTT 客户端实例
   * @param on_message 回调函数指针，当有消息到达时调用
   */
  mosquitto_message_callback_set(mosq, callback);
}
